home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * © Copyright 1982-1992, Rob Glanville
- *
- * by Rob Glanville
- *
- * 07 Sep 92 - V1.02
- *
- * robix.c - Debugger foundation
- *
- */
-
- #include <stdio.h> /* Only needed when running under an O.S. */
-
- #define UInt8 unsigned char
- #define UInt16 unsigned short
- #define UInt32 unsigned long
- #define True 0xffffffff
- #define False 0x00000000
- #define CR 0x0d
- #define LF 0x0a
- #define Rubout 0x08
- #define Tab 0x09
- #define NOP 0x00
- #define Null 0x00
- #define Blank 0x20
-
- /************************************* Variables *********************************************/
-
- UInt8 CommandLine[256]; /* Input buffer */
- UInt8 delimiter; /* Delimiter between arguments */
- UInt8 AsciiBuf[19]; /* A buffer for output */
- UInt8 Argument[0x80]; /* The arguments go here one by one */
- UInt8 TabSize; /* Size of tab stops */
-
- UInt16 ArgSize; /* Argument size */
- UInt16 CPointer; /* Command pointer */
- UInt16 slotPtr; /* A logical index to the slot where 1=9 */
-
- UInt32 CommandIndex; /* The index into command buffer */
- UInt32 number; /* A place for all numbers input */
- UInt32 BufPtr; /* Alias buffer pointer for unions */
- UInt32 RobBase;
-
- /************************************* Constants *********************************************/
-
- UInt8 Digits[] = {"0123456789ABCDEF"};
- UInt8 Delimiters[] = {0x09,0x0a,0x1b,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
- 0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x3a,
- 0x3b,0x3c,0x3d,0x3e,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,
- 0x00,0x60,0x7b,0x7c,0x7d,0x7e,0x7f,0x3f,0x0d};
-
- /************************************* Routines **********************************************/
-
- /*
- getch and putchar are the only interface that needs to be modified for
- different environments. If you don't have an O.S. to call then you have
- to write these routines yourself and they would talk directly to hardware.
- */
- unsigned char getch() {
- UInt8 character;
- do {
- character = getchar();
- } while (character == 0xff);
- return(character);
- }
-
- void printstr(string)
- UInt8 *string;
- {
- while (*string != Null) putchar(*string++);
- }
-
- void SyntaxError() {
- printstr("Syntax error\n");
- }
-
- /*
- LineIn get input from the user and places it in a command lime buffer
- for later parsing. This is nothing more than echo characters with rubouts
- and tabs.
- */
- void LineIn() {
- UInt8 character,exit;
- UInt16 index,TabSpace;
- if (delimiter == CR) {
- CommandIndex = Null;
- exit = False;
- CPointer = Null;
- do {
- character = getch();
- if (character == Rubout) {
- if (CommandIndex > 0) {
- putchar(Rubout);
- putchar(Blank);
- putchar(Rubout);
- CommandIndex--;
- }
- }
- else if (character == CR) {
- putchar(CR); /* */
- CommandLine[CommandIndex++] = CR;
- exit = True;
- }
- else if (character == Tab) {
- TabSpace = TabSize - ((CommandIndex+1) % TabSize);
- for (index=0;index<TabSpace;index++) {
- putchar(Blank);
- CommandLine[CommandIndex++] = Blank;
- }
- }
- else {
- /* putchar(character); /* Some interfaces like MPW already echo the characters */
- CommandLine[CommandIndex++] = character;
- }
- } while (!exit);
- }
- else delimiter = CR;
- }
-
- /*
- Takes a pointer to a character and changes lower case to upper case.
- */
- void Upper(character) UInt8 *character; {
- if ((*character >= 'a') && (*character <= 'z')) *character -= Blank;
- }
-
- /*
- ScanDelimiters simply sets the command line pointer to point to the
- first non delimiter so the user can type garbage and there won't be
- a syntax error.
- */
- void ScanDelimiters() {
- UInt16 index;
- UInt8 found;
- do {
- found = False;
- for (index=0;index<sizeof(Delimiters)-2;index++) {
- if (CommandLine[CPointer] == Delimiters[index]) found = True;
- }
- if (found) CPointer++;
- } while (found);
- }
-
- /*
- getarg simply parses the command line and places and arguments in
- a buffer called 'Argument'. Whatever delimiter is found is placed
- in 'delimiter' and the variable 'ArgSize' has the byte count of
- the argument. You make a call to getarg and check the size for non-zero
- to tell when one is found. Keep making calls until you get an argument
- or the delimiter is a cursor return which indicates the end of the
- command line. If you want a number, then use GetValue.
- */
- void getarg() {
- UInt16 index,ArgPtr;
- UInt8 found;
- ArgPtr = Null;
- do {
- found = False;
- for (index=0;index<sizeof(Delimiters);index++) {
- if (CommandLine[CPointer] == Delimiters[index]) {
- delimiter = Delimiters[index];
- if (delimiter != CR) CPointer++;
- found = True;
- break;
- }
- }
- if (!found) Argument[ArgPtr++] = CommandLine[CPointer++];
- } while (!found);
- Argument[ArgPtr] = Null;
- ArgSize = ArgPtr;
- }
-
- /*
- GetValue returns true if a hexadecimal number was found in the
- command line. Otherwise it returns false. If a nubmer is found,
- it is placed in the global variable called 'number'. Repeated
- calls to GetValue will get multiple parameters to use in a command.
- */
- UInt16 GetValue() {
- UInt8 found;
- UInt16 index,loop;
- if (delimiter == ',') return(False);
- found = False;
- number = Null;
- do {
- getarg(); /* Get one argument from the command line */
- if (ArgSize) {
- /* Check for all digits in the argument */
- for (index=0;index<ArgSize;) {
- Upper(&Argument[index]);
- found = False;
- for (loop=0;loop<0x10;loop++) {
- if (Argument[index] == Digits[loop]) {
- Argument[index] = loop;
- found = True;
- break;
- }
- }
- if (!found) break;
- else index++;
- }
- /* Convert ascii to hex */
- if (found) for (index=0;index<ArgSize;index++) {
- number = ((number * 0x10) + Argument[index]);
- }
- }
- } while ((!found) && (delimiter != CR) && (delimiter != ','));
- return(found);
- }
-
- void nibble(data) UInt8 data; {
- if (data > 9) putchar(data + '7');
- else putchar(data + '0');
- }
-
- void byteout(data) UInt8 data; {
- nibble((data / 0x10) & 0x0f);
- nibble(data & 0x0f);
- }
-
- void wordout(data) UInt16 data; {
- byteout((UInt8)(data / 0x100) & 0xff);
- byteout((UInt8)data & 0xff);
- }
-
- void longout(data) UInt32 data; {
- wordout((UInt16)(data / 0x10000) & 0xffff);
- wordout((UInt16)data & 0xffff);
- }
-
- void crlf() { printstr("\n"); }
-
- /************************************* Commands *********************************************/
-
- /*
- AlterMemory gets the address and data from the command line and
- alters that location. If no data is given the the user is prompted
- for it.
- */
- UInt16 AlterMemory() {
- UInt32 Address;
- UInt8 databyte;
- if (!GetValue()) return(True);
- Address = number;
- if (GetValue()) {
- do {
- *(UInt8 *)Address++ = number;
- } while (GetValue());
- return(False);
- }
- else while(True) {
- longout(Address);
- putchar(Blank);
- databyte = *(UInt8 *)Address;
- byteout(databyte);
- putchar('-');
- LineIn(); /* Get input from user for next value */
- ScanDelimiters();
- if (!GetValue()) return(False);
- *(UInt8 *)Address++ = number;
- }
- }
-
- UInt16 DisplayMemory() {
- UInt32 Start,Length,index,Aindex,Sindex;
- register UInt8 databyte;
- if (!GetValue()) return(True);
- Start = number;
- if (GetValue()) Length = number;
- else Length = 0x10;
- if (Length == 0) Length = 1;
- index = Null;
- Aindex = Null;
- do {
- if ((index % 0x10) == 0x00) longout(Start);
- putchar(Blank);
- databyte = *(UInt8 *)Start;
- if ((databyte >= Blank) && (databyte <= 0x7e)) AsciiBuf[Aindex++] = databyte;
- else AsciiBuf[Aindex++] = '.';
- Start++;
- byteout(databyte);
- if ((index % 0x10) == 0x0f) {
- AsciiBuf[16] = CR;
- AsciiBuf[17] = Null;
- putchar(Blank);
- putchar(Blank);
- printstr(&AsciiBuf);
- Aindex = Null;
- }
- } while (++index<Length);
- if ((index % 0x10) != Null) {
- Sindex = 0x10 - (index % 0x10);
- for (index=0;index<Sindex;index++) printstr(" ");
- AsciiBuf[Aindex] = Null;
- printstr(" ");
- printstr(&AsciiBuf);
- crlf();
- }
- return(False);
- }
-
- UInt16 FillMemory() {
- UInt32 Start,Length,Value,index;
- UInt8 increment;
- if (!GetValue()) return(True);
- Start = number;
- if (!GetValue()) return(True);
- Length = number;
- if (Length == 0) Length = 1;
- if (!GetValue()) {
- if (Argument[0] == 'I') {
- increment = True;
- Value = 0;
- }
- else return(True);
- }
- else {
- increment = False;
- Value = number;
- }
- for (index=0;index<Length;index++) {
- *(UInt8 *)Start++ = Value;
- if (increment) Value++;
- }
- return(False);
- }
-
- /* Fill in the help menu when you add a new command */
- void Help() {
- printstr("?) Print this menu\n");
- printstr("A) Alter memory\n");
- /* printstr("B) \n"); */
- /* printstr("C) \n"); */
- printstr("D) Display memory\n");
- /* printstr("E) \n"); */
- printstr("F) Fill memory\n");
- /* printstr("G) \n"); */
- /* printstr("H) \n"); */
- /* printstr("I) \n"); */
- /* printstr("J) \n"); */
- /* printstr("K) \n"); */
- /* printstr("L) \n"); */
- /* printstr("M) \n"); */
- /* printstr("N) \n"); */
- /* printstr("O) \n"); */
- /* printstr("P) \n"); */
- /* printstr("Q) \n"); */
- /* printstr("R) \n"); */
- /* printstr("S) \n"); */
- /* printstr("T) \n"); */
- /* printstr("U) \n"); */
- /* printstr("V) \n"); */
- /* printstr("W) \n"); */
- /* printstr("X) \n"); */
- /* printstr("Y) \n"); */
- /* printstr("Z) \n"); */
- }
-
- /************************************* Main Loop ********************************************/
-
- void main() {
- UInt8 Exit;
- delimiter = CR;
- TabSize = 8;
- Exit = False;
- printstr("ROBIX\n");
- while (!Exit) {
- if (delimiter == CR) printstr(">");
- LineIn();
- ScanDelimiters(); /* Point to first non Blank */
- Upper(&CommandLine[CPointer]);
- switch(CommandLine[CPointer++]) {
- case '?' :
- Help();
- break;
- case CR :
- break;
- case 'A' :
- if (AlterMemory()) SyntaxError();
- break;
- /* case 'B' :
- break;
- case 'C' :
- break;
- */ case 'D' :
- if (DisplayMemory()) SyntaxError();
- break;
- /* case 'E' :
- break;
- */ case 'F' :
- if (FillMemory()) SyntaxError();
- break;
- /* case 'G' :
- break;
- case 'H' :
- break;
- case 'I' :
- break;
- case 'J' :
- break;
- case 'K' :
- break;
- case 'L' :
- break;
- case 'M' :
- break;
- case 'N' :
- break;
- case 'O' :
- break;
- case 'P' :
- break;
- case 'Q' :
- break;
- case 'R' :
- break;
- case 'S' :
- break;
- case 'T' :
- break;
- case 'U' :
- break;
- case 'V' :
- break;
- case 'W' :
- break;
- case 'X' :
- break;
- case 'Y' :
- break;
- case 'Z' :
- break;
- */ default :
- printstr("Unknown command\n");
- delimiter = CR;
- break;
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-